<template>
    <div class="product-edit">
        <el-card class="box-card">
            <div slot="header" class="clearfix">
                <span>{{ isEdit ? '商品编辑' : '商品上架' }}</span>
            </div>
            <el-form :model="form" :rules="rules" ref="form" label-width="120px">
                <!-- 基本信息 -->
                <el-divider content-position="left">基本信息</el-divider>
                <el-form-item label="商品名称" prop="title">
                    <el-input v-model="form.title" placeholder="请输入商品名称"></el-input>
                </el-form-item>
                <el-form-item label="副标题" prop="subtitle">
                    <el-input v-model="form.subtitle" placeholder="请输入副标题"></el-input>
                </el-form-item>
                <el-form-item label="品牌" prop="brand">
                    <el-input v-model="form.brand" placeholder="请输入品牌"></el-input>
                </el-form-item>
                <el-form-item label="商品分类" prop="categoryPath">
                    <el-cascader v-model="form.categoryPath" :options="categories" :props="{
                        checkStrictly: false,
                        value: 'id',
                        label: 'name',
                        children: 'children',
                        emitPath: true,
                        changeOnSelect: false
                    }" @change="handleCategoryChange" placeholder="请选择商品分类"></el-cascader>
                </el-form-item>

                <!-- 价格库存 -->
                <el-divider content-position="left">价格/库存</el-divider>
                <el-form-item label="销售价" prop="price">
                    <el-input-number v-model="form.price" :precision="2" :step="0.1" :min="0"></el-input-number>
                </el-form-item>
                <el-form-item label="原价" prop="originalPrice">
                    <el-input-number v-model="form.originalPrice" :precision="2" :step="0.1" :min="0"></el-input-number>
                </el-form-item>
                <el-form-item label="库存" prop="stock">
                    <el-input-number v-model="form.stock" :min="0" :step="1"></el-input-number>
                </el-form-item>

                <!-- 图片信息 -->
                <el-divider content-position="left">图片信息</el-divider>
                <!-- 主图上传组件 -->
                <el-form-item label="主图" prop="mainImage">
                    <!-- el-upload 用于上传商品主图，单文件上传，上传前和上传成功有专用钩子 -->
                    <el-upload class="avatar-uploader" :action="ossUploadHost" :data="ossUploadData"
                        :show-file-list="false" :before-upload="beforeMainImageUpload"
                        :on-success="handleMainImageSuccess">
                        <!-- v-if: 已有主图时显示图片预览和操作按钮 -->
                        <template v-if="form.mainImage">
                            <div class="avatar-wrapper">
                                <img :src="form.mainImage" class="avatar" />
                                <span class="el-upload-list__item-status-label">
                                    <i class="el-icon-upload-success el-icon-check"></i>
                                </span>
                                <div class="avatar-actions">
                                    <i class="el-icon-zoom-in" @click.stop="handleMainImagePreview"></i>
                                    <i class="el-icon-delete" @click.stop="handleMainImagenRemove"></i>
                                </div>
                            </div>
                        </template>
                        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                    </el-upload>
                </el-form-item>
                <!-- 图片集上传组件 -->
                <el-form-item label="图片集" prop="images">
                    <el-upload :action="ossUploadHost" :http-request="ossUploadRequest" list-type="picture-card"
                        :file-list="imageList" :on-preview="handlePictureCardPreview" :on-remove="handleRemove"
                        :before-upload="beforeImageUpload" :on-success="handleImageSuccess" multiple>
                        <i class="el-icon-plus"></i>
                    </el-upload>

                    <!-- 图片预览弹窗 -->
                    <el-dialog :visible.sync="dialogVisible">
                        <img width="100%" :src="dialogImageUrl" alt="">
                    </el-dialog>
                </el-form-item>

                <!-- 商品详情 -->
                <el-divider content-position="left">商品详情</el-divider>
                <el-form-item label="商品描述" prop="description">
                    <el-input type="textarea" :rows="4" placeholder="请输入商品描述" v-model="form.description"></el-input>
                </el-form-item>

                <!-- 其他设置 -->
                <el-divider content-position="left">其他设置</el-divider>
                <el-form-item label="商品状态" prop="status">
                    <el-radio-group v-model="form.status">
                        <el-radio :label="1">上架</el-radio>
                        <el-radio :label="0">下架</el-radio>
                    </el-radio-group>
                </el-form-item>

                <!-- 提交按钮 -->
                <el-form-item>
                    <el-button type="primary" @click="submitForm('form')">
                        {{ isEdit ? '保存修改' : '立即创建' }}
                    </el-button>
                    <el-button v-if="isEdit" @click="goBack">返回列表</el-button>
                    <el-button v-else @click="resetForm('form')">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>
    </div>
</template>
<script>
import { getProductDetail, saveProduct, getOssPolicy } from '@/api/product'
import { getCategoryTree } from '@/api/category'

export default {
    name: 'ProductEdit',
    data() {
        return {
            // 是否为编辑模式（true=编辑，false=新增）
            isEdit: false,
            // 商品表单数据
            form: {
                id: "", // 商品ID
                title: "", // 商品名称
                subtitle: "", // 副标题
                brand: "", // 品牌
                categoryId: "", // 分类ID
                categoryPath: [], // 分类路径（级联）
                mainImage: "", // 主图URL
                images: "", // 图片集URL（逗号分隔）
                description: "", // 商品描述
                price: 0, // 销售价
                originalPrice: 0, // 原价
                stock: 0, // 库存
                status: 1 // 上架状态 1=上架 0=下架
            },
            // 表单校验规则
            rules: { // 表单校验规则
                title: [
                    { required: true, message: '请输入商品名称', trigger: 'blur' },
                    { min: 2, max: 100, message: '长度在 2 到 100 个字符', trigger: 'blur' }
                ],
                categoryPath: [
                    { required: true, message: '请选择商品分类', trigger: 'change' },
                    {
                        validator: (rule, value, callback) => {
                            if (!value || value.length !== 3) callback(new Error('请选择第三级分类'))
                            else callback()
                        }, trigger: 'change'
                    }
                ],
                price: [{ required: true, message: '请输入销售价', trigger: 'blur' }],
                stock: [{ required: true, message: '请输入库存', trigger: 'blur' }],
                mainImage: [{ required: true, message: '请上传商品主图', trigger: 'change' }]
            },
            categories: [], // 商品分类树
            imageList: [], // 图片集文件列表
            dialogImageUrl: "", // 图片预览弹窗 URL
            dialogVisible: false, // 图片预览弹窗显示状态
            showMainImageSuccess: false, // 主图上传成功标记
            ossUploadHost: "",
            ossUploadData: {} // OSS 上传签名参数
        }
    },
    async created() {
        await this.loadCategories()
        // await this.getOssPolicy()
        const id = this.$route.params.id
        this.isEdit = !!id
        if (this.isEdit) {
            await this.loadProductData(id)
        }
    },
    methods: {
        // 加载商品分类树，递归清理空 children
        async loadCategories() {
            try {
                const res = await getCategoryTree()
                if (res.code === 0) {
                    function cleanCategoryChildren(list) {
                        if (!Array.isArray(list)) return;
                        list.forEach(item => {
                            if (Array.isArray(item.children)) {
                                if (item.children.length === 0) {
                                    delete item.children;
                                } else {
                                    cleanCategoryChildren(item.children);
                                }
                            }
                        });
                    }
                    cleanCategoryChildren(res.data);
                    this.categories = res.data
                }
            } catch (error) {
                this.$message.error('获取商品分类失败')
            }
        },
        // 加载商品详情（编辑模式）
        async loadProductData(id) {
            try {
                const res = await getProductDetail(id)
                if (res.code === 0) {
                    const product = res.data
                    this.form = {
                        ...product,
                        categoryPath: product.categoryPath
                            ? product.categoryPath.replace(/^,|,$/g,"").split(',').filter(Boolean)
                            : []
                    }
                    if (product.images) {
                        this.imageList = product.images.split(',').map(url => ({
                            url,
                            name: url.substring(url.lastIndexOf('/') + 1)
                        }))
                    }
                } else {
                    this.$message.error('获取商品信息失败')
                    this.goBack()
                }
            } catch (error) {
                // 可补充捕获异常时的提示等逻辑，比如 this.$message.error('加载商品详情出错')
                this.$message.error('获取商品信息失败');
                this.goBack()
            }
        },
        handleCategoryChange(value) {
            if (value && value.length > 0) {
                this.form.categoryId = value[value.length - 1];
            }
        },
        // 获取 OSS 上传签名参数
        async getOssPolicy() {
            try {
                const res = await getOssPolicy();
                if (res.code === 0) {
                    const data = res.data;
                    this.ossUploadHost = data.host;
                    this.ossUploadData = {
                        OSSAccessKeyId: data.accessid,
                        policy: data.policy,
                        signature: data.signature,
                        dir: data.dir,
                        host: data.host,
                        expire: data.expire
                    };
                }
            } catch (error) {
                this.$message.error('获取上传配置失败');
            }
        },
        // 主图上传前处理，刷新 OSS 签名并校验图片格式和大小，避免导致上传失败
        async beforeMainImageUpload(file) {
            await this.getOssPolicy();
            this.showMainImageSuccess = false;
            const isImage = file.type.startsWith('image/');
            const isLt2M = file.size / 1024 / 1024 < 2;
            if (!isImage) {
                this.$message.error('上传文件只能是图片格式!');
                return false;
            }
            if (!isLt2M) {
                this.$message.error('上传图片大小不能超过 2MB!');
                return false;
            }
            const suffix = file.name.substring(file.name.lastIndexOf('.'))
            const filename = Date.now() + suffix
            this.ossUploadData.key = this.ossUploadData.dir + filename
            return true
        },
        async beforeImageUpload(file) {
            await this.getOssPolicy();
            const isImage = file.type.startsWith('image/');
            const isLt2M = file.size / 1024 / 1024 < 2;
            if (!isImage) this.$message.error('只能上传图片');
            if (!isLt2M) this.$message.error('图片不能超过 2MB');
            return isImage && isLt2M;
        },
        // 主图上传成功回调，设置主图 URL
        handleMainImageSuccess(res, file) {
            this.form.mainImage = this.ossUploadHost + '/' + this.ossUploadData.key;
            this.showMainImageSuccess = true;
            this.$message.success('上传成功');
        },
        // 图片集上传成功回调，维护图片列表和图片集 URL
        handleImageSuccess(res, file, fileList) {
            if (file && res && res.key) {
                file.url = this.ossUploadHost + '/' + res.key;
            }
            this.imageList = fileList.map(f => {
                if (f.response && f.response.key) {
                    f.url = this.ossUploadHost + '/' + f.response.key;
                }
                return f;
            });
            this.form.images = this.imageList.map(item => item.url).join(',');
            this.$message.success('上传成功');
        },
        // 图片预览弹窗
        handlePictureCardPreview(file) {
            this.dialogImageUrl = file.url;
            this.dialogVisible = true;
        },
        // 移除图片集中的图片
        handleRemove(file, fileList) {
            this.imageList = fileList;
            this.form.images = fileList.map(item => item.url).join(',');
        },
        handleMainImagePreview() {
            this.dialogImageUrl = this.form.mainImage;
            this.dialogVisible = true;
        },
        // 主图删除
        handleMainImageRemove() {
            this.form.mainImage = "";
            this.showMainImageSuccess = false;
        },
        // 自定义图片集上传请求，适配 OSS 直传
        ossUploadRequest(option) {
            const file = option.file;
            const suffix = file.name.substring(file.name.lastIndexOf('.'));
            const filename = Date.now() + '_' + Math.floor(Math.random() * 10000) + suffix;
            const key = this.ossUploadData.dir + filename;
            const formData = new FormData();
            formData.append('key', key);
            formData.append('OSSAccessKeyId', this.ossUploadData.OSSAccessKeyId);
            formData.append('policy', this.ossUploadData.policy);
            formData.append('signature', this.ossUploadData.signature);
            formData.append('success_action_status', '200');
            formData.append('file', file);
            const xhr = new XMLHttpRequest();
            xhr.open('POST', this.ossUploadHost, true);
            xhr.onload = () => {
                if (xhr.status === 200) {
                    file.url = this.ossUploadHost + '/' + key;
                    option.onSuccess({ key }, file);
                } else {
                    option.onError(new Error('上传失败'));
                }
            };
            xhr.onerror = () => {
                option.onError(new Error('上传失败'));
            };
            xhr.send(formData);
        },
        // 提交表单，区分新增/编辑，校验通过后保存商品
        submitForm(formName) {
            this.$refs[formName].validate(async (valid) => {
                if (valid) {
                    try {
                        this.form.categoryId = this.form.categoryPath.length > 0
                            ? this.form.categoryPath[this.form.categoryPath.length - 1]
                            : "";
                        this.form.categoryPath = ',' + this.form.categoryPath.join(',') + ',';
                        const res = await saveProduct(this.form);
                        if (res.code === 0) {
                            this.$message.success(this.isEdit ? '商品更新成功' : '商品上架成功');
                            this.$router.push('/product/list');
                        }
                    } catch (error) {
                        this.$message.error(this.isEdit ? '商品更新失败' : '商品创建失败');
                    }
                }
            });
        },
        goBack() {
            this.$router.push('/product/list');
        },
        resetForm(formName) {
            this.$refs[formName].resetFields();
            this.form.mainImage = "";
            this.form.images = "";
            this.imageList = [];
        }
    }
}
</script>

<style scoped>
.product-edit {
    padding: 20px;
}

.avatar-uploader {
    width: 148px;
    height: 148px;
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
}

.avatar-uploader:hover {
    border-color: #409EFF;
}

.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 148px;
    height: 148px;
    line-height: 148px;
    text-align: center;
}

.avatar {
    width: 148px;
    height: 148px;
    display: block;
}

.avatar-wrapper {
    position: relative;
    display: inline-block;
}

.avatar-actions {
    display: none;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.4);
    color: #fff;
    align-items: center;
    justify-content: center;
    z-index: 2;
    font-size: 22px;
}

.avatar-wrapper:hover .avatar-actions {
    display: flex;
}

.avatar-actions i {
    margin: 0 8px;
    cursor: pointer;
    transition: color 0.2s;
}

.avatar-actions i:hover {
    color: #409EFF;
}

.avatar-wrapper .el-upload-list__item-status-label {
    position: absolute;
    right: 0;
    top: 0;
    width: 32px;
    height: 32px;
    z-index: 10;
    pointer-events: none;
    background: transparent;
    display: flex;
    align-items: flex-start;
    justify-content: flex-end;
    padding: 0;
}

.avatar-wrapper .el-upload-list__item-status-label:after {
    content: '';
    position: absolute;
    right: 0;
    top: 0;
    width: 0;
    height: 0;
    border-top: 32px solid #13ce66;
    border-left: 32px solid transparent;
    z-index: 10;
}

.avatar-wrapper .el-upload-list__item-status-label .el-icon-upload-success {
    position: absolute;
    right: 2px;
    top: 2px;
    font-size: 14px;
    color: #fff;
    z-index: 11;
    transform: rotate(-0deg);
    font-weight: normal;
    pointer-events: none;
}

.avatar-wrapper:hover .el-upload-list__item-status-label {
    display: none !important;
}
</style>